
require(['blasteroids/gamestate', 'blasteroids/ship', 'blasteroids/star', 'blasteroids/images', 'jquery'], function (GameState, Ship, Star, Images, $) {
    $('#connect').click(function(){
        var username = $('#username').val();
        var server = $('#server').val();
        var port = $('#port').val();
        var color = $('#color').val();
        var image = $('input:radio[name=shipColor]:checked').val();
        if(!username || !server || !port || !image){
            alert('all fields must have values');
            return false;
        }
        
        var controls = {
            40:'shoot',
            13:'respawn',
            38:'accelerate',
            37:'left',
            39:'right',
            81:'viewStats'
        }
        var keysDown = {};
        var gameState = new GameState();
        $(function () {
            "use strict";
    
            // if user is running mozilla then use it's built-in WebSocket
            window.WebSocket = window.WebSocket || window.MozWebSocket;

            // if browser doesn't support WebSocket, just show some notification and exit
            if (!window.WebSocket) {
                document.write('Sorry, but your browser doesn\'t support WebSockets.');
                return;
            }
            
            var ship = new Ship(username, 0, gameState.canvasSize, color, image);
            var joinedGame = false;

            // open connection
            var connection = new WebSocket('ws://'+ server+':'+ port);
            connection.onopen = function () {
            };
            connection.onerror = function (error) {
                alert('error' + JSON.stringify(error));
            };
            connection.onclose = function (error) {
                alert('Connection closed by the server. Contact the server administrator if problems persist');
            };
            
            $('#joinGame').click(function(){
                if(!joinedGame){
                    var action = {
                        'type':'joinGame',
                        'data':{
                            'name':ship.name,
                            'color':ship.color,
                            'image':ship.image
                        }
                    };
                    connection.send(JSON.stringify(action));
                    if(!gameState.addShip(ship)){
                        alert('can\'t add');
                    }
                    joinedGame = true;
                    $('#joinGame').hide();
                }
            });
                
            //most important part - incoming messages
            connection.onmessage = function (message) {
                var packet = JSON.parse(message.data);
                if(packet.type == 'action'){
                    gameState.processAction(packet.data);
                }else if(packet.type == 'gameState'){
                    gameState.setInfo(packet.data);
                }else if(packet.type == 'joinGame'){
                    gameState.addShip(new Ship(packet.data.name, 0, gameState.canvasSize, packet.data.color, packet.data.image));
                }
            };
    
            var accelerating = false; //will need to refactor this
    
            addEventListener("keydown", function (e) {
                var actionText = '';
                if(controls[e.keyCode] == 'shoot'){
                    actionText = 'shoot';
                }else if(controls[e.keyCode] == 'respawn'){
                    actionText = 'respawn';
                }else if(controls[e.keyCode] == 'accelerate'){
                    if(!accelerating){
                        actionText = 'accelerate';
                        accelerating = true;
                    }
                }else if(controls[e.keyCode] == 'left'){
                    actionText = 'turnLeft';
                }else if(controls[e.keyCode] == 'right'){
                    actionText = 'turnRight';
                }
                if(actionText != '' && joinedGame){
                    var action = {
                        player:ship.name,
                        data:actionText
                    };
                    gameState.processAction(action);
                    connection.send(JSON.stringify({
                        type:'action',
                        data:action
                    }));
                }
                    
                if(controls[e.keyCode]){
                    keysDown[controls[e.keyCode]] = true;
                }
            }, false);
                
            addEventListener("keyup", function (e) {
                var actionText = '';
                if(controls[e.keyCode] == 'shoot'){
                    actionText = 'reload';
                }else if(controls[e.keyCode] == 'accelerate'){
                    actionText = 'unaccelerate';
                    accelerating = false;
                }else if(controls[e.keyCode] == 'left'){
                    actionText = 'unTurnLeft';
                }else if(controls[e.keyCode] == 'right'){
                    actionText = 'unTurnRight';
                }
                if(actionText != '' && joinedGame){
                    var action = {
                        player:ship.name,
                        data:actionText
                    };
                    gameState.processAction(action);
                    connection.send(JSON.stringify({
                        type:'action',
                        data:action
                    }));
                }
                if(controls[e.keyCode]){
                    delete keysDown[controls[e.keyCode]];	
                }
            }, false);
        });
            
        //canvas stuff
        //add the canvas
        var canvas = document.createElement("canvas");
        var ctx = canvas.getContext("2d");
        canvas.width = 1200;
        canvas.height = 600;
        $('#connectionInformation').hide();
        $('#canvasBox').append(canvas);
        var objects = new Array();
            
        Array.prototype.remove = function(from, to) {
            var rest = this.slice((to || from) + 1 || this.length);
            this.length = from < 0 ? this.length + from : from;
            return this.push.apply(this, rest);
        };

        // Draw everything
        var drawGame = function () {
            ctx.fillStyle = '#000000';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
              
            $.each(objects, function(index, value){
                value.draw(ctx);
            });
            gameState.draw(ctx, Images);
            if(keysDown['viewStats']){
                drawStats(ctx);
            }
        };
        // Update everything
        var then = new Date();
        var update = function () {
            var now = new Date();
            var modifier = (now-then)/1000;
            gameState.update(modifier);
            $.each(objects, function(index, value){
                value.update(modifier);
            });
            then = now;
        };

        for(var i=0; i<100; i++){
            objects.push(new Star(canvas.width, canvas.height));
        }
        
        //the main game loop
        var main = function(){
            update();
            drawGame();
        }
        setInterval(update, 1);
        setInterval(drawGame, 1);
            
        var drawStats = function(context){
            var location = {
                x:400, 
                y:200
            };
            context.fillStyle = '#FFFFFF';
            context.font = "bold 16px monospace";
            context.fillText('                Name|' +'  '+ 'kills|' + '  ' + 'death|'+ '  ' + 'score|', location.x, location.y); 
            $.each(gameState.ships, function(key, value) {
                location.y += 20;
                context.fillStyle = value.color;
                context.fillText(JSON.stringify(value.getStatsInfo()), location.x, location.y); 
            });
        };
    });
});
